#include "ProxyPac.h"

// Functions to implement are here:
// - http://linuxmafia.com/faq/Web/autoproxy.html
// - http://www.returnproxy.com/proxypac/static/netscape-proxy-format.html

ProxyPac::ProxyPac()
{

}

QScriptValue ProxyPac::dnsResolve(QScriptContext *context, QScriptEngine *engine) {
   Q_UNUSED(engine)
   QString toResolve = context->argument(0).toString();
   qDebug() << "dnsResolve - toResolve: " << toResolve;

   QHostInfo info = QHostInfo::fromName(toResolve);
   if ( info.error() == QHostInfo::NoError ) {
      return info.addresses().first().toString(); //< Pick the first one
   } else {
      return QString("Host not found");
   }
}

QScriptValue ProxyPac::isPlainHostName(QScriptContext *context, QScriptEngine *engine) {
   Q_UNUSED(engine)
   QString hostname = context->argument(0).toString();
   qDebug() << "isPlainHostName - hostname: " << hostname;

   return hostname.contains('.') ? false : true;
}

QScriptValue ProxyPac::isInNet(QScriptContext *context, QScriptEngine *engine) {
   Q_UNUSED(engine)
   QString host = context->argument(0).toString();
   QHostAddress hostAddress;
   QPair<QHostAddress, int> subnet;
   QString pattern = context->argument(1).toString();
   QString mask = context->argument(2).toString();
   qDebug() << "isInNet - host: " << host;
   qDebug() << "isInNet - pattern: " << pattern;
   qDebug() << "isInNet - mask: " << mask;

   QHostInfo info = QHostInfo::fromName(host);
   if ( info.error() == QHostInfo::NoError ) {
      hostAddress = info.addresses().first();
      subnet = QHostAddress::parseSubnet(QString("%1/%2").arg(pattern,mask));
      qDebug() << "Host "<< host << " is in Subnet " << QString("%1/%2").arg(pattern,mask) << "? " << hostAddress.isInSubnet(subnet);
      return hostAddress.isInSubnet(subnet);
   } else {
      return false;
   }
}

QScriptValue ProxyPac::myIpAddress(QScriptContext *context, QScriptEngine *engine) {
   Q_UNUSED(context)
   Q_UNUSED(engine)

   QScriptValue  retour;
   foreach ( QHostAddress address, QNetworkInterface::allAddresses() ) {
      if( !address.isNull()
         && address != QHostAddress::Null
         && address != QHostAddress::LocalHost
         && address != QHostAddress::LocalHostIPv6
         && address != QHostAddress::Broadcast
         && address != QHostAddress::Any
         && address != QHostAddress::AnyIPv6
         ) {
         qDebug() << "myIpAddress - " << address.toString();
         retour = address.toString(); //< Pick the First one
         break;
      }
   }

   return retour;
}

QScriptValue ProxyPac::shExpMatch(QScriptContext *context, QScriptEngine *engine) {
    Q_UNUSED(engine)

    QString host = context->argument(0).toString();
    QString pattern = context->argument(1).toString();

    QRegularExpression *regex = new QRegularExpression(pattern);
    QRegularExpressionMatch match = regex->match(host);

    return match.hasMatch();
}

QScriptValue ProxyPac::localHostOrDomainIs(QScriptContext *context, QScriptEngine *engine) {
    return false;
}
QScriptValue ProxyPac::dnsDomainIs(QScriptContext *context, QScriptEngine *engine) {
    return false;
}

/*int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);

   QScriptEngine engine;
   QString str;

   // Read the PAC file in a String
   QFile scriptFile("C:\Users\segard_d\AppData\Roaming\Juniper Networks\Network Connect 7.1.7\instantproxy.pac");
   if ( !scriptFile.open(QIODevice::ReadOnly|QIODevice::Text) ) {
      return EXIT_FAILURE;
   }
   str = scriptFile.readAll();
   scriptFile.close();

   // Inject the extra JS function as explained above
   QScriptValue dnsResolveFunction = engine.newFunction(dnsResolve);
   engine.globalObject().setProperty("dnsResolve", dnsResolveFunction);
   QScriptValue isPlainHostNameFunction = engine.newFunction(isPlainHostName);
   engine.globalObject().setProperty("isPlainHostName", isPlainHostNameFunction);
   QScriptValue isInNetFunction = engine.newFunction(isInNet);
   engine.globalObject().setProperty("isInNet", isInNetFunction);
   QScriptValue myIpAddressFunction = engine.newFunction(myIpAddress);
   engine.globalObject().setProperty("myIpAddress", myIpAddressFunction);

   // Evalute the PAC file
   if ( engine.canEvaluate(str) ) {
      engine.evaluate(str);
      QScriptValue ctor = engine.evaluate("FindProxyForURL(\"http://blog.orangelabsuk.com\", \"blog.orangelabsuk.com\")");
      if ( !ctor.isError() ) {
         qDebug() << ctor.toString();
         return EXIT_SUCCESS;
      }
   }

   qDebug() << "Error Occurred";
   return EXIT_FAILURE;
}*/
